home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / NewsWatcher 2.0d17 Source / source / prefsdlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-18  |  25.1 KB  |  974 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     prefsdlog.c
  4.  
  5.     This module handles the preferences dialog.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <Packages.h>
  15.  
  16. #include "glob.h"
  17. #include "prefsdlog.h"
  18. #include "dlgutil.h"
  19. #include "util.h"
  20. #include "popup.h"
  21. #include "font.h"
  22. #include "sfutil.h"
  23. #include "log.h"
  24.  
  25.  
  26.  
  27. /* Items common to all topics. The kInit and kTerm items are pseudo-items
  28.    used to intialize and terminate the topics. The OK and Cancel buttons
  29.    are also common to all topics (item numbers 1 and 2). */
  30.  
  31. #define kTopicPopup            3
  32. #define kInit                100
  33. #define kTerm                101
  34.  
  35. #define kPrefsDlg            300
  36. #define kGeneralOptions        1
  37. #define kServerAddresses    2
  38. #define kServerOptions        3
  39. #define kPersonalInfo        4
  40. #define kSignature            5
  41. #define kRemoteHost            6
  42. #define kFontSize            7
  43. #define kSavedText            8
  44. #define kAuthorization        9
  45.  
  46. /* General options topic. */
  47.  
  48. #define kShowAuthors        4
  49. #define kShowHeaders        5
  50. #define kCollapseThreads    6
  51. #define kKeypadShortcuts    7
  52. #define kZoomWindows        8
  53. #define kShowKilled            9
  54. #define kCopyReplies        10
  55. #define kCheckNewGroups        11
  56. #define kAreYouSure            12
  57. #define kLogActionsToFile    13
  58. #define kAutoSaveOnQuit        14
  59. #define kExpandHilited        15
  60. #define kMaxArticles        17
  61.  
  62. /* Server info topic. */
  63.  
  64. #define kNewsServer            6
  65. #define kMailServer            8
  66.  
  67. /* Server options topic. */
  68.  
  69. #define kBatchedGroupCmds    5
  70. #define kUseXPAT            6
  71. #define kNoNewConnection    7
  72. #define kNoModeReader        8
  73.  
  74. /* Personal info topic. */
  75.  
  76. #define kFullName            6
  77. #define kOrganization        8
  78. #define kMailAddress        10
  79.  
  80. /* Signature topic. */
  81.  
  82. #define kSigStaticText        4
  83. #define kSignature            5
  84. #define kAddSigSeparator    6
  85.  
  86. /* Remote host info topic. */
  87.  
  88. #define    kRemoteHost            6
  89. #define    kRemoteLogin        8
  90. #define    kRemotePassword        10
  91. #define kRemotePath            12
  92. #define kAutoGetPut            13
  93. #define    kSavePassword        14
  94.  
  95. /* Font/size topic. */
  96.  
  97. #define kListFontPopup         5
  98. #define kListSizeBox        7
  99. #define kListSizePopup        8
  100. #define kListSample            9
  101. #define kListVertLine        10
  102. #define kTextFontPopup        12
  103. #define kTextSizeBox        14
  104. #define kTextSizePopup        15
  105. #define kTextSample            16
  106.  
  107. /* Saved text file topic. */
  108.  
  109. #define kAppBorder            5
  110. #define kAppName            6
  111. #define kAppButton            7
  112. #define kDirCheckBox        8
  113. #define kDirBorder            9
  114. #define kDirName            10
  115. #define kDirButton            11
  116.  
  117. /* Authoriation topic. */
  118.  
  119.  
  120.  
  121.  
  122. static Str255 gStaticText;        /* static text for signature dialog */
  123.  
  124. static short gListFontID;        /* current list font id */
  125. static short gListFontSize;        /* current list font size */
  126. static short gTextFontID;        /* current text font id */
  127. static short gTextFontSize;        /* current text font size */
  128.  
  129.  
  130.  
  131. /*----------------------------------------------------------------------------
  132.     GeneralOptions
  133.  
  134.     Handles the general options preferences dialog.
  135.     
  136.     Entry:    prefs = pointer to new prefs.
  137.             dlg = pointer to dialog.
  138.             item = item number hit.
  139. ----------------------------------------------------------------------------*/
  140.  
  141. static void GeneralOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  142. {
  143.     switch (item) {
  144.     
  145.         case kInit:
  146.         
  147.             DlgSetCheck(dlg, kShowAuthors, prefs->showAuthors);
  148.             DlgSetCheck(dlg, kShowHeaders, prefs->showHeaders);
  149.             DlgSetCheck(dlg, kCollapseThreads, prefs->showThreadsCollapsed);
  150.             DlgSetCheck(dlg, kKeypadShortcuts, prefs->keypadShortcuts);
  151.             DlgSetCheck(dlg, kZoomWindows, prefs->zoomWindows);
  152.             DlgSetCheck(dlg, kShowKilled, prefs->showKilledArticles);
  153.             DlgSetCheck(dlg, kCopyReplies, prefs->replyCC);
  154.             DlgSetCheck(dlg, kCheckNewGroups, prefs->checkForNewGroups);
  155.             DlgSetCheck(dlg, kAreYouSure, prefs->areYouSureAlert);
  156.             DlgSetCheck(dlg, kLogActionsToFile, prefs->logActionsToFile);
  157.             DlgSetCheck(dlg, kAutoSaveOnQuit, prefs->autoSaveOnQuit);
  158.             DlgSetCheck(dlg, kExpandHilited, prefs->expandHilited);
  159.             DlgSetNumber(dlg, kMaxArticles, prefs->maxFetch);
  160.             SetItemNumeric(dlg, kMaxArticles, true);
  161.             SetItemMaxLength(dlg, kMaxArticles, 6);
  162.             SelIText(dlg, kMaxArticles, 0, 0x7fff);
  163.             #ifndef FILTERS
  164.                 DlgSetCheck(dlg, kShowKilled, false);
  165.                 DlgSetCheck(dlg, kExpandHilited, false);
  166.                 DlgEnableItem (dlg, kShowKilled, false);
  167.                 DlgEnableItem (dlg, kExpandHilited, false);
  168.             #endif
  169.             break;
  170.             
  171.         case kTerm:
  172.             
  173.             prefs->showAuthors = DlgGetCheck(dlg, kShowAuthors);
  174.             prefs->showHeaders = DlgGetCheck(dlg, kShowHeaders);
  175.             prefs->showThreadsCollapsed = DlgGetCheck(dlg, kCollapseThreads);
  176.             prefs->keypadShortcuts = DlgGetCheck(dlg, kKeypadShortcuts);
  177.             prefs->zoomWindows = DlgGetCheck(dlg, kZoomWindows);
  178.             prefs->showKilledArticles = DlgGetCheck(dlg, kShowKilled);
  179.             prefs->replyCC = DlgGetCheck(dlg, kCopyReplies);
  180.             prefs->checkForNewGroups = DlgGetCheck(dlg, kCheckNewGroups);
  181.             prefs->areYouSureAlert = DlgGetCheck(dlg, kAreYouSure);
  182.             prefs->logActionsToFile = DlgGetCheck(dlg, kLogActionsToFile);
  183.             prefs->autoSaveOnQuit = DlgGetCheck(dlg, kAutoSaveOnQuit);
  184.             prefs->expandHilited = DlgGetCheck(dlg, kExpandHilited);
  185.             prefs->maxFetch = DlgGetNumber(dlg, kMaxArticles);
  186.             break;
  187.             
  188.         case kShowAuthors:
  189.         case kShowHeaders:
  190.         case kCollapseThreads:
  191.         case kKeypadShortcuts:
  192.         case kZoomWindows:
  193.         case kShowKilled:
  194.         case kCopyReplies:
  195.         case kCheckNewGroups:
  196.         case kAreYouSure:
  197.         case kLogActionsToFile:
  198.         case kAutoSaveOnQuit:
  199.         case kExpandHilited:
  200.         
  201.             DlgToggleCheck(dlg, item);
  202.             break;
  203.             
  204.     }
  205. }
  206.  
  207.  
  208.  
  209. /*----------------------------------------------------------------------------
  210.     Server
  211.  
  212.     Handles the server info preferences dialog.
  213.     
  214.     Entry:    prefs = pointer to new prefs.
  215.             dlg = pointer to dialog.
  216.             item = item number hit.
  217. ----------------------------------------------------------------------------*/
  218.  
  219. static void Server (TPrefRec *prefs, DialogPtr dlg, short item)
  220. {
  221.     Boolean enable;
  222.  
  223.     switch (item) {
  224.     
  225.         case kInit:
  226.         
  227.             DlgSetPString(dlg, kNewsServer, prefs->newsServerName);
  228.             SetItemMaxLength(dlg, kNewsServer, 255);
  229.             DlgSetPString(dlg, kMailServer, prefs->mailServerName);
  230.             SetItemMaxLength(dlg, kMailServer, 255);
  231.             if (*prefs->newsServerName == 0) {
  232.                 SelIText(dlg, kNewsServer, 0, 0);
  233.             } else if (*prefs->mailServerName == 0) {
  234.                 SelIText(dlg, kMailServer, 0, 0);
  235.             } else {
  236.                 SelIText(dlg, kNewsServer, 0, 0x7fff);
  237.             }
  238.             break;
  239.             
  240.         case kTerm:
  241.             
  242.             break;
  243.             
  244.         case kNewsServer:
  245.         case kMailServer:
  246.         
  247.             DlgGetPString(dlg, kNewsServer, prefs->newsServerName);
  248.             DlgGetPString(dlg, kMailServer, prefs->mailServerName);
  249.             enable = *prefs->newsServerName != 0 && *prefs->mailServerName != 0;
  250.             DlgEnableItem(dlg, ok, enable);
  251.             DlgEnableItem(dlg, kTopicPopup, enable);
  252.             
  253.     }
  254. }
  255.  
  256.  
  257.  
  258. /*----------------------------------------------------------------------------
  259.     ServerOptions
  260.  
  261.     Handles the server options preferences dialog.
  262.     
  263.     Entry:    prefs = pointer to new prefs.
  264.             dlg = pointer to dialog.
  265.             item = item number hit.
  266. ----------------------------------------------------------------------------*/
  267.  
  268. static void ServerOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  269. {
  270.     switch (item) {
  271.     
  272.         case kInit:
  273.         
  274.             DlgSetCheck(dlg, kBatchedGroupCmds, prefs->batchedGroupCmds);
  275.             DlgSetCheck(dlg, kUseXPAT, prefs->useXPAT);
  276.             DlgSetCheck(dlg, kNoNewConnection, prefs->noNewConnection);
  277.             DlgSetCheck(dlg, kNoModeReader, prefs->noModeReader);
  278.             break;
  279.             
  280.         case kTerm:
  281.             
  282.             prefs->batchedGroupCmds = DlgGetCheck(dlg, kBatchedGroupCmds);
  283.             prefs->useXPAT = DlgGetCheck(dlg, kUseXPAT);
  284.             prefs->noNewConnection = DlgGetCheck(dlg, kNoNewConnection);
  285.             prefs->noModeReader = DlgGetCheck(dlg, kNoModeReader);
  286.             break;
  287.             
  288.         case kBatchedGroupCmds:
  289.         case kUseXPAT:
  290.         case kNoNewConnection:
  291.         case kNoModeReader:
  292.         
  293.             DlgToggleCheck(dlg, item);
  294.             break;
  295.             
  296.     }
  297. }
  298.  
  299.  
  300.  
  301. /*----------------------------------------------------------------------------
  302.     Personal
  303.  
  304.     Handles the personal info preferences dialog.
  305.     
  306.     Entry:    prefs = pointer to new prefs.
  307.             dlg = pointer to dialog.
  308.             item = item number hit.
  309. ----------------------------------------------------------------------------*/
  310.  
  311. static void Personal (TPrefRec *prefs, DialogPtr dlg, short item)
  312. {
  313.     switch (item) {
  314.     
  315.         case kInit:
  316.         
  317.             DlgSetCString(dlg, kFullName, prefs->fullName);
  318.             SetItemMaxLength(dlg, kFullName, 255);
  319.             DlgSetCString(dlg, kOrganization, prefs->organization);
  320.             SetItemMaxLength(dlg, kOrganization, 255);
  321.             DlgSetCString(dlg, kMailAddress, prefs->address);
  322.             SetItemMaxLength(dlg, kMailAddress, 255);
  323.             if (*prefs->fullName == 0) {
  324.                 SelIText(dlg, kFullName, 0, 0);
  325.             } else if (*prefs->organization == 0) {
  326.                 SelIText(dlg, kOrganization, 0, 0);
  327.             } else if (*prefs->address == 0) {
  328.                 SelIText(dlg, kMailAddress, 0, 0);
  329.             } else {
  330.                 SelIText(dlg, kFullName, 0, 0x7fff);
  331.             }
  332.             break;
  333.             
  334.         case kTerm:
  335.             
  336.             DlgGetCString(dlg, kFullName, prefs->fullName);
  337.             DlgGetCString(dlg, kOrganization, prefs->organization);
  338.             break;
  339.             
  340.         case kMailAddress:
  341.         
  342.             DlgGetCString(dlg, kMailAddress, prefs->address);
  343.             DlgEnableItem(dlg, ok, *prefs->address != 0);
  344.             DlgEnableItem(dlg, kTopicPopup, *prefs->address != 0);
  345.             
  346.     }
  347. }
  348.  
  349.  
  350.  
  351. /*----------------------------------------------------------------------------
  352.     DrawSigStaticText
  353.  
  354.     This user item procedure draws the static text item in the signature dialog. 
  355.     We need this because the dialog's font has been changed for editing the
  356.     signature.
  357.     
  358.     Entry:    dlg = pointer to dialog.
  359.             item = item number.
  360. ----------------------------------------------------------------------------*/
  361.  
  362. static pascal void DrawSigStaticText (DialogPtr dlg, short item)
  363. {
  364.     short itemType;
  365.     Handle itemHandle;
  366.     Rect box;
  367.     short oldFontNum, oldFontSize;
  368.     
  369.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  370.     oldFontNum = dlg->txFont;
  371.     oldFontSize = dlg->txSize;
  372.     TextFont(0);
  373.     TextSize(12);
  374.     TextBox(gStaticText+1, *gStaticText, &box, teJustLeft);
  375.     TextFont(oldFontNum);
  376.     TextSize(oldFontSize);
  377. }
  378.  
  379.  
  380.  
  381. /*----------------------------------------------------------------------------
  382.     Signature
  383.  
  384.     Handles the signature preferences dialog.
  385.     
  386.     Entry:    prefs = pointer to new prefs.
  387.             dlg = pointer to dialog.
  388.             item = item number hit.
  389. ----------------------------------------------------------------------------*/
  390.  
  391. static void Signature (TPrefRec *prefs, DialogPtr dlg, short item)
  392. {
  393.     short fontNum, fontSize;
  394.     short itemType;
  395.     Rect box;
  396.     Handle itemHandle;
  397.     TEHandle textH;
  398.     FontInfo fontInfo;
  399.     short itemSize;
  400.  
  401.     switch (item) {
  402.     
  403.         case kInit:
  404.         
  405.             DlgSetCheck(dlg, kAddSigSeparator, prefs->addSigSeparatorLine);
  406.         
  407.             /* Stuff the signature (maybe longer than 255) into the item */
  408.             
  409.             GetDItem(dlg, kSignature, &itemType, &itemHandle, &box);
  410.             PtrToXHand(prefs->signature, itemHandle, strlen(prefs->signature));
  411.             SelIText(dlg, kSignature, 0, 0x7fff);
  412.             SetItemReturnIsLegal(dlg, kSignature, true);
  413.             SetItemMaxLength(dlg, kSignature, 4095);
  414.     
  415.             /* Set the dialog's text edit area to use a different font */
  416.             
  417.             SetPort(dlg);
  418.             GetFNum(prefs->textFont, &fontNum);
  419.             fontSize = prefs->textSize;
  420.             textH = ((DialogPeek)dlg)->textH;
  421.             (**textH).txFont = fontNum;        /* Set it for TextEdit */
  422.             (**textH).txSize = fontSize;
  423.             TextFont(fontNum);                /* And for QuickDraw */
  424.             TextSize(fontSize);
  425.             GetFontInfo(&fontInfo);            /* Adjust the TE line heights */
  426.             (**textH).lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
  427.             (**textH).fontAscent = fontInfo.ascent;
  428.             TECalText(textH);
  429.     
  430.             /* Change the static text into a userItem so it can use the system font */
  431.             
  432.             GetDItem(dlg, kSigStaticText, &itemType, &itemHandle, &box);
  433.             GetIText(itemHandle, gStaticText);
  434.             SetDItem(dlg, kSigStaticText, userItem, (Handle)DrawSigStaticText, &box);
  435.             break;
  436.             
  437.         case kTerm:
  438.             
  439.             prefs->addSigSeparatorLine = DlgGetCheck(dlg, kAddSigSeparator);
  440.             GetDItem(dlg, kSignature, &itemType, &itemHandle, &box);
  441.             itemSize = GetHandleSize(itemHandle);
  442.             BlockMove(*itemHandle, prefs->signature, itemSize);
  443.             prefs->signature[itemSize] = 0;
  444.     
  445.             /* Reset the dialog's text edit area to Chicago 12 */
  446.             
  447.             SetPort(dlg);
  448.             fontNum = 0;
  449.             fontSize = 12;
  450.             textH = ((DialogPeek)dlg)->textH;
  451.             (**textH).txFont = fontNum;        /* Set it for TextEdit */
  452.             (**textH).txSize = fontSize;
  453.             TextFont(fontNum);                /* And for QuickDraw */
  454.             TextSize(fontSize);
  455.             GetFontInfo(&fontInfo);            /* Adjust the TE line heights */
  456.             (**textH).lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
  457.             (**textH).fontAscent = fontInfo.ascent;
  458.             TECalText(textH);
  459.             break;
  460.             
  461.         case kAddSigSeparator:
  462.         
  463.             DlgToggleCheck(dlg, kAddSigSeparator);
  464.             break;
  465.             
  466.     }
  467. }
  468.  
  469.  
  470.  
  471. /*----------------------------------------------------------------------------
  472.     Remote
  473.  
  474.     Handles the remote host info preferences dialog.
  475.     
  476.     Entry:    prefs = pointer to new prefs.
  477.             dlg = pointer to dialog.
  478.             item = item number hit.
  479. ----------------------------------------------------------------------------*/
  480.  
  481. static void Remote (TPrefRec *prefs, DialogPtr dlg, short item)
  482. {
  483.     CStr255 tempStr;
  484.     short len;
  485.  
  486.     switch (item) {
  487.     
  488.         case kInit:
  489.         
  490.             DlgSetCString(dlg, kRemoteHost, prefs->host);
  491.             SetItemMaxLength(dlg, kRemoteHost, 255);
  492.             DlgSetCString(dlg, kRemoteLogin, prefs->name);
  493.             SetItemMaxLength(dlg, kRemoteLogin, 255);
  494.             len = strlen(prefs->remotePassword);
  495.             memset(tempStr, '•', len);
  496.             tempStr[len] = 0;
  497.             DlgSetCString(dlg, kRemotePassword, tempStr);
  498.             SetItemPassword(dlg, kRemotePassword, prefs->remotePassword);
  499.             SetItemMaxLength(dlg, kRemotePassword, 31);
  500.             DlgSetCString(dlg, kRemotePath, prefs->remotePath);
  501.             SetItemMaxLength(dlg, kRemotePath, 31);
  502.             DlgSetCheck(dlg, kAutoGetPut, prefs->autoFetchnewsrc);
  503.             DlgSetCheck(dlg, kSavePassword, prefs->savePassword);
  504.             if (*prefs->host == 0) {
  505.                 SelIText(dlg, kRemoteHost, 0, 0);
  506.             } else if (*prefs->name == 0) {
  507.                 SelIText(dlg, kRemoteLogin, 0, 0);
  508.             } else if (*prefs->remotePassword == 0) {
  509.                 SelIText(dlg, kRemotePassword, 0, 0);
  510.             } else if (*prefs->remotePath == 0) {
  511.                 SelIText(dlg, kRemotePath, 0, 0);
  512.             } else {
  513.                 SelIText(dlg, kRemoteHost, 0, 0x7fff);
  514.             }
  515.             break;
  516.             
  517.         case kTerm:
  518.             
  519.             DlgGetCString(dlg, kRemoteHost, prefs->host);
  520.             DlgGetCString(dlg, kRemoteLogin, prefs->name);
  521.             DlgGetCString(dlg, kRemotePath, prefs->remotePath);
  522.             prefs->autoFetchnewsrc = DlgGetCheck(dlg, kAutoGetPut);
  523.             prefs->savePassword = DlgGetCheck(dlg, kSavePassword);
  524.             break;
  525.         
  526.         case kSavePassword:
  527.         case kAutoGetPut:
  528.         
  529.             DlgToggleCheck(dlg, item);
  530.             break;
  531.             
  532.     }
  533. }
  534.  
  535.  
  536.  
  537. /*----------------------------------------------------------------------------
  538.     DrawFontSample
  539.     
  540.     A user item procedure to draw the font samples.
  541.     
  542.     Entry:    dlg = pointer to dialog.
  543.             item = item number.
  544. ----------------------------------------------------------------------------*/
  545.  
  546. static pascal void DrawFontSample (DialogPtr dlg, short item)
  547. {
  548.     short itemType;
  549.     Rect box;
  550.     Handle itemHandle;
  551.     StringPtr text;
  552.     short fontID, fontSize, saveFont, saveSize;
  553.     GrafPtr curPort;
  554.  
  555.     DlgGrayBorderItem(dlg, item);
  556.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  557.     if (item == kListSample) {
  558.         text = "\pThis is the font and size in which NewsWatcher group and subject lists are displayed.";
  559.         fontID = gListFontID;
  560.         fontSize = gListFontSize;
  561.     } else {
  562.         text = "\pThis is the font and size in which NewsWatcher article and message windows are displayed.";
  563.         fontID = gTextFontID;
  564.         fontSize = gTextFontSize;
  565.     }
  566.     GetPort(&curPort);
  567.     saveFont = curPort->txFont;
  568.     saveSize = curPort->txSize;
  569.     TextFont(fontID);
  570.     TextSize(fontSize);
  571.     InsetRect(&box, 2, 2);
  572.     TextBox(text + 1, *text, &box, teFlushDefault);
  573.     TextFont(saveFont);
  574.     TextSize(saveSize);
  575. }
  576.  
  577.  
  578.  
  579. /*----------------------------------------------------------------------------
  580.     RedrawSample
  581.  
  582.     Force one of the sample text items to be redrawn.
  583.     
  584.     Entry:    dlg = pointer to dialog.
  585.             item = item number.
  586. ----------------------------------------------------------------------------*/
  587.  
  588. static void RedrawSample (DialogPtr dlg, short item)
  589. {
  590.     short itemType;
  591.     Handle itemHandle;
  592.     Rect box;
  593.     
  594.     SetPort(dlg);
  595.     GetDItem(dlg, item, &itemType, &itemHandle, &box);
  596.     InsetRect(&box, 2, 2);
  597.     EraseRect(&box);
  598.     InvalRect(&box);
  599. }
  600.  
  601.  
  602.  
  603. /*----------------------------------------------------------------------------
  604.     SetNewFont
  605.  
  606.     Set a new font in the font/size dialog.
  607.     
  608.     Entry:    dlg = pointer to dialog.
  609.             listFont = true if list font, false if text font.
  610.             fontNum = new font number.
  611. ----------------------------------------------------------------------------*/
  612.  
  613. static void SetNewFont (DialogPtr dlg, Boolean listFont, short fontNum)
  614. {
  615.     short numItems, itemType, i;
  616.     Rect box;
  617.     Handle itemHandle;
  618.     Str255 itemStr, fontName;
  619.     ControlHandle ctl;
  620.     long size;
  621.  
  622.     /* Select the right font in the font popup menu. */
  623.     
  624.     ctl = DlgGetControl(dlg, listFont ? kListFontPopup : kTextFontPopup);
  625.     GetFontName(fontNum, fontName);
  626.     SetPopupValue(ctl, fontName, false);
  627.     
  628.     /* Adjust the size popup so the nice sizes are outlined. */
  629.  
  630.     ctl = DlgGetControl(dlg, listFont ? kListSizePopup : kTextSizePopup);
  631.     numItems = GetCtlMax(ctl);
  632.     for (i = 1; i <= numItems; i++) {
  633.         GetPopupPString(ctl, i, itemStr);
  634.         StringToNum(itemStr, &size);
  635.         if (RealFont(fontNum, (short)size)) {
  636.             SetPopupItemStyle(ctl, i, outline);
  637.         } else {
  638.             SetPopupItemStyle(ctl, i, 0);
  639.         }
  640.     }
  641.  
  642.     /* Force the sample text to be redrawn */
  643.     
  644.     RedrawSample(dlg, listFont ? kListSample : kTextSample);
  645. }
  646.  
  647.  
  648.  
  649. /*----------------------------------------------------------------------------
  650.     FontIDFromPopup
  651.  
  652.     Get the font ID corresponding the currently selected font in a popup menu.
  653.     
  654.     Entry:    dlg = pointer to dialog.
  655.             item = item number of popup menu.
  656. ----------------------------------------------------------------------------*/
  657.  
  658. static short FontIDFromPopup (DialogPtr dlg, short item)
  659. {
  660.     ControlHandle ctl;
  661.     short fontNum;
  662.     Str255 fontName;
  663.  
  664.     ctl = DlgGetControl(dlg, item);
  665.     GetPopupPString(ctl, kCurrentPopupItem, fontName);
  666.     GetFNum(fontName, &fontNum);
  667.     return fontNum;
  668. }
  669.  
  670.  
  671.  
  672. /*----------------------------------------------------------------------------
  673.     Font
  674.  
  675.     Handles the font and size preferences dialog.
  676.     
  677.     Entry:    prefs = pointer to new prefs.
  678.             dlg = pointer to dialog.
  679.             item = item number hit.
  680. ----------------------------------------------------------------------------*/
  681.  
  682. static void Font (TPrefRec *prefs, DialogPtr dlg, short item)
  683. {
  684.     Str255 tempStr;
  685.     long num;
  686.  
  687.     switch (item) {
  688.     
  689.         case kInit:
  690.         
  691.             GetFNum(prefs->listFont, &gListFontID);
  692.             gListFontSize = prefs->listSize;
  693.             SetNewFont(dlg, true, gListFontID);
  694.             DlgSetNumber(dlg, kListSizeBox, gListFontSize);
  695.             SetItemNumeric(dlg, kListSizeBox, true);
  696.             SetItemMaxLength(dlg, kListSizeBox, 2);
  697.             SelIText(dlg, kListSizeBox, 0, 0x7fff);
  698.             SetItemPopupTypeinItem(dlg, kListSizePopup, kListSizeBox);
  699.             
  700.             GetFNum(prefs->textFont, &gTextFontID);
  701.             gTextFontSize = prefs->textSize;
  702.             SetNewFont(dlg, false, gTextFontID);
  703.             DlgSetNumber(dlg, kTextSizeBox, gTextFontSize);
  704.             SetItemNumeric(dlg, kTextSizeBox, true);
  705.             SetItemMaxLength(dlg, kTextSizeBox, 2);
  706.             SetItemPopupTypeinItem(dlg, kTextSizePopup, kTextSizeBox);
  707.             
  708.               DlgSetUserItem(dlg, kListSample, DrawFontSample);
  709.               DlgSetUserItem(dlg, kTextSample, DrawFontSample);
  710.               DlgSetUserItem(dlg, kListVertLine, DlgGrayBorderItem);
  711.             break;
  712.             
  713.         case kTerm:
  714.             
  715.               GetFontName(gListFontID, prefs->listFont);
  716.               GetFontName(gTextFontID, prefs->textFont);
  717.               prefs->listSize = gListFontSize;
  718.               prefs->textSize = gTextFontSize;
  719.             break;
  720.             
  721.         case kListFontPopup:
  722.         
  723.               gListFontID = FontIDFromPopup(dlg, item);
  724.               SetNewFont(dlg, true, gListFontID);
  725.             break;
  726.             
  727.         case kTextFontPopup:
  728.         
  729.               gTextFontID = FontIDFromPopup(dlg, item);
  730.               SetNewFont(dlg, false, gTextFontID);
  731.             break;            
  732.           
  733.         case kListSizePopup:
  734.         
  735.               GetPopupPString(DlgGetControl(dlg, item), kCurrentPopupItem, tempStr);
  736.               DlgSetPString(dlg, kListSizeBox, tempStr);
  737.               SelIText(dlg, kListSizeBox, 0, 0x7fff);
  738.             /* Fall through! */
  739.             
  740.         case kListSizeBox:
  741.         
  742.               DlgGetPString(dlg, kListSizeBox, tempStr);
  743.               StringToNum(tempStr, &num);
  744.               if (num != 0 && num != gListFontSize) {
  745.                   gListFontSize = num;
  746.                   RedrawSample(dlg, kListSample);
  747.               }
  748.             break;
  749.           
  750.         case kTextSizePopup:
  751.         
  752.               GetPopupPString(DlgGetControl(dlg, item), kCurrentPopupItem, tempStr);
  753.               DlgSetPString(dlg, kTextSizeBox, tempStr);
  754.               SelIText(dlg, kListSizeBox, 0, 0x7fff);
  755.             /* Fall through! */
  756.             
  757.         case kTextSizeBox:
  758.         
  759.               DlgGetPString(dlg, kTextSizeBox, tempStr);
  760.               StringToNum(tempStr, &num);
  761.               if (num != 0 && num != gTextFontSize) {
  762.                   gTextFontSize = num;
  763.                   RedrawSample(dlg, kTextSample);
  764.               }
  765.             break;
  766.             
  767.     }
  768. }
  769.  
  770.  
  771.  
  772. /*----------------------------------------------------------------------------
  773.     Saved
  774.  
  775.     Handles the saved text file preferences dialog.
  776.     
  777.     Entry:    prefs = pointer to new prefs.
  778.             dlg = pointer to dialog.
  779.             item = item number hit.
  780. ----------------------------------------------------------------------------*/
  781.  
  782. static void Saved (TPrefRec *prefs, DialogPtr dlg, short item)
  783. {
  784.     StandardFileReply reply;
  785.     FInfo fInfo;
  786.     long dirID;
  787.     Str31 name;
  788.     OSErr err;
  789.     CInfoPBRec cpb;
  790.     HParamBlockRec pb;
  791.  
  792.     switch (item) {
  793.     
  794.         case kInit:
  795.  
  796.               DlgSetUserItem(dlg, kAppBorder, DlgGrayBorderItem);
  797.             DlgSetPString(dlg, kAppName, prefs->textCreatorName);
  798.             DlgSetCheck(dlg, kDirCheckBox, prefs->textDefaultDir);
  799.               DlgSetUserItem(dlg, kDirBorder, DlgGrayBorderItem);            
  800.             err = VolNameToVRefNum (prefs->textVolName, &cpb.dirInfo.ioVRefNum);
  801.               if (err == noErr) {
  802.                 cpb.dirInfo.ioNamePtr = name;
  803.                 cpb.dirInfo.ioFDirIndex = -1;
  804.                 cpb.dirInfo.ioDrDirID = prefs->textDirID;
  805.                 err = PBGetCatInfo(&cpb, false);
  806.             }
  807.             if (err != noErr) *name = 0;
  808.             DlgSetPString(dlg, kDirName, name);
  809.             DlgEnableItem(dlg, kDirButton, prefs->textDefaultDir);
  810.                 
  811.             break;
  812.             
  813.         case kTerm:
  814.         
  815.             break;
  816.             
  817.         case kAppButton:
  818.         
  819.             MyStandardGetFile(nil, 1, (OSType*)"APPL", &reply);
  820.             if (!reply.sfGood) break;
  821.             FSpGetFInfo(&reply.sfFile, &fInfo);
  822.             prefs->textCreator = fInfo.fdCreator;
  823.             pstrcpy(prefs->textCreatorName, reply.sfFile.name);
  824.             DlgSetPString(dlg, kAppName, prefs->textCreatorName);
  825.             break;
  826.             
  827.         case kDirCheckBox:
  828.         
  829.             DlgToggleCheck(dlg, item);
  830.             prefs->textDefaultDir = DlgGetCheck(dlg, item);
  831.             DlgEnableItem(dlg, kDirButton, prefs->textDefaultDir);
  832.             break;
  833.             
  834.         case kDirButton:
  835.         
  836.             MyStandardGetDirectory(&reply, &dirID);
  837.             if (!reply.sfGood) break;
  838.             prefs->textDirID = dirID;
  839.             pb.volumeParam.ioNamePtr = prefs->textVolName;
  840.             pb.volumeParam.ioVRefNum = reply.sfFile.vRefNum;
  841.             pb.volumeParam.ioVolIndex = 0;
  842.             PBHGetVInfo(&pb, false);
  843.             DlgSetPString(dlg, kDirName, reply.sfFile.name);
  844.             break;
  845.             
  846.     }
  847. }
  848.  
  849.  
  850.  
  851. /*----------------------------------------------------------------------------
  852.     Auth
  853.  
  854.     Handles the authorization preferences dialog.
  855.     
  856.     Entry:    prefs = pointer to new prefs.
  857.             dlg = pointer to dialog.
  858.             item = item number hit.
  859. ----------------------------------------------------------------------------*/
  860.  
  861. static void Auth (TPrefRec *prefs, DialogPtr dlg, short item)
  862. {
  863.     switch (item) {
  864.     
  865.         case kInit:
  866.         
  867.             break;
  868.             
  869.         case kTerm:
  870.             
  871.             break;
  872.             
  873.     }
  874. }
  875.  
  876.  
  877.  
  878. /*----------------------------------------------------------------------------
  879.     DoPrefsDialog
  880.  
  881.     Presents the Preferences dialog.
  882. ----------------------------------------------------------------------------*/
  883.  
  884.  
  885. void DoPrefsDialog (void)
  886. {
  887.     typedef void (*prefsFuncPtr) (TPrefRec *prefs, DialogPtr dlg, short item);
  888.     
  889.     static prefsFuncPtr prefsFuncPtrs[] = {
  890.         GeneralOptions,
  891.         Server,
  892.         ServerOptions,
  893.         Personal,
  894.         Signature,
  895.         Remote,
  896.         Font,
  897.         Saved,
  898.         Auth,
  899.     };
  900.  
  901.     static short curTopic = kGeneralOptions;
  902.     
  903.     short newTopic;
  904.     prefsFuncPtr theFunc;
  905.     TPrefRec *prefs;
  906.     DialogPtr dlg;
  907.     short item;
  908.     CStr255 msg;
  909.     Boolean listFontChanged, textFontChanged;
  910.     Handle theDITL;
  911.     
  912.     prefs = (TPrefRec*)MyNewPtr(sizeof(TPrefRec));
  913.     *prefs = gPrefs;
  914.     
  915.     dlg = MyGetNewDialog(kPrefsDlg);
  916.     theDITL = GetResource('DITL', kPrefsDlg + curTopic);
  917.     MyAppendDITL(dlg, theDITL, overlayDITL);
  918.     ReleaseResource(theDITL);
  919.     DlgSetCtlValue(dlg, kTopicPopup, curTopic);
  920.     theFunc = prefsFuncPtrs[curTopic - 1];
  921.     (*theFunc)(prefs, dlg, kInit);
  922.     ShowWindow(dlg);
  923.     
  924.     while (true) {
  925.         MyModalDialog(DialogFilter, &item, true, curTopic != kSignature);
  926.         if (item == ok || item == cancel) {
  927.             (*theFunc)(prefs, dlg, kTerm);
  928.             break;
  929.         } else if (item == kTopicPopup) {
  930.             newTopic = DlgGetCtlValue(dlg, kTopicPopup);
  931.             if (newTopic != curTopic) {
  932.                 (*theFunc)(prefs, dlg, kTerm);
  933.                 curTopic = newTopic;
  934.                 MyShortenDITL(dlg, CountDITL(dlg) - 3);
  935.                 theDITL = GetResource('DITL', kPrefsDlg + curTopic);
  936.                 MyAppendDITL(dlg, theDITL, overlayDITL);
  937.                 ReleaseResource(theDITL);
  938.                 theFunc = prefsFuncPtrs[curTopic - 1];
  939.                 (*theFunc)(prefs, dlg, kInit);
  940.             }
  941.         } else {
  942.             (*theFunc)(prefs, dlg, item);
  943.         }
  944.     }
  945.     
  946.     MyDisposDialog(dlg);
  947.     
  948.     if (item == ok) {
  949.         if (prefs->logActionsToFile && !gPrefs.logActionsToFile) {
  950.             OpenLogFile();
  951.         } else if (!prefs->logActionsToFile && gPrefs.logActionsToFile) {
  952.             CloseLogFile();
  953.         }
  954.         if (!EqualString(prefs->newsServerName, gPrefs.newsServerName, false, true)) {
  955.             strcpy(msg, "You must quit and restart the program ");
  956.             strcat(msg, "for the news server change to take effect.");
  957.             ErrorMessage(msg);
  958.         }
  959.         listFontChanged = prefs->listSize != gPrefs.listSize ||
  960.             !EqualString(prefs->listFont, gPrefs.listFont, false, true);
  961.         textFontChanged = prefs->textSize != gPrefs.textSize ||
  962.             !EqualString(prefs->textFont, gPrefs.textFont, false, true);
  963.         gPrefs = *prefs;
  964.         if (listFontChanged) {
  965.             gPrefs.maxGroupNameWidth = 0;
  966.             FontWasChanged(true);
  967.         }
  968.         if (textFontChanged) {
  969.             FontWasChanged(false);
  970.         }
  971.     }
  972.     MyDisposPtr((Ptr)prefs);
  973. }
  974.